package com.thinkit.bigdata.web.service.impl.perCenter;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.base.Strings;
import com.thinkit.bigdata.core.feature.orm.mybatis.Page;
import com.thinkit.bigdata.core.util.DateFormatUtil;
import com.thinkit.bigdata.core.util.es.ESUtil;
import com.thinkit.bigdata.web.controller.pubmet.PubMethod;
import com.thinkit.bigdata.web.dao.bus.*;
import com.thinkit.bigdata.web.model.BaseEntity;
import com.thinkit.bigdata.web.model.bus.*;
import com.thinkit.bigdata.web.model.es.audioEs.*;
import com.thinkit.bigdata.web.model.result.Constants;
import com.thinkit.bigdata.web.model.result.HtmlResult;
import com.thinkit.bigdata.web.model.sec.User;
import com.thinkit.bigdata.web.service.perCenter.PerCenDetService;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.converters.DateConverter;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.session.Session;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.*;

/**
 *
 * Created by hccl on 2018/9/5.
 */
@Service
public class PerCenDetServiceImpl implements PerCenDetService {

    @Resource
    private ESUtil esUtil;

    @Resource
    private BusModelMapper modelMapper;

    @Resource
    private BusTagMapper busTagMapper;

    @Resource
    private BusModelRuleMapper busModelRuleMapper;

    @Resource
    private BusModelMapper busModelMapper;

    @Resource
    private BusWorkMapper busWorkMapper;

    @Resource
    private BusWorkModelMapper busWorkModelMapper;

    @Override
    public HtmlResult getDataBySerialNumber(String serialNumber) throws IOException {
        Source source = esUtil.getSourceBySerialNumber(serialNumber);
        return HtmlResult.success(source.getVoiceInfo());
    }

    @Override
    public HtmlResult getWorkScoreSerialNumber(HttpServletRequest request) throws IOException {
        String serialNumber = request.getParameter("serialNumber");//录音流水
        String workId = request.getParameter("workId");//任务id
        String taskType = request.getParameter("taskType");//录音流水
        Source source = esUtil.getSourceBySerialNumber(serialNumber);
        if ("model".equals(taskType)) {
            for (TestInfos testInfos : source.getTestInfos()) {
                if (workId.equals(testInfos.getWorkId().toString())) {
                    return HtmlResult.success(testInfos.getWorkScore(), "ok");
                }
            }
        } else {
            for (WorkScores workScores : source.getWorkScores()) {
                if (workId.equals(workScores.getWorkId().toString())) {
                    return HtmlResult.success(workScores.getWorkScore(), "ok");
                }
            }
        }
        return HtmlResult.failure();
    }

    @Override
    public HtmlResult getSttInfoBySerialNumber(String serialNumber) throws IOException {
        Source source = esUtil.getSourceBySerialNumber(serialNumber);
        List<SttSentences> sttSentences =  source.getSttInfo().getSttSentences();
        if (sttSentences == null && source.getVoiceInfo().getProStatus() == 3) {
            return HtmlResult.failure("语音转写异常.....");
        } else if (sttSentences == null && source.getVoiceInfo().getProStatus() < 3) {
            return HtmlResult.failure("正在转写中.....");
        }
        //TODO为结果排序
        Collections.sort(sttSentences, new Comparator<SttSentences>() {
            /*
             * int compare(Student o1, Student o2) 返回一个基本类型的整型，
             * 返回负数表示：o1 小于o2，
             * 返回0 表示：o1和o2相等，
             * 返回正数表示：o1大于o2。
             */
            public int compare(SttSentences o1, SttSentences o2) {

                //按照Start进行升序排列
                if (Double.valueOf(o1.getStart()) > Double.valueOf(o2.getStart())) {
                    return 1;
                }
                if (Double.valueOf(o1.getStart()) == Double.valueOf(o2.getStart())) {
                    return 0;
                }
                return -1;
            }
        });
        return HtmlResult.success(sttSentences);
    }

    @Override
    public HtmlResult getTagsBySerialNumber(String serialNumber) throws IOException {
        Source source = esUtil.getSourceBySerialNumber(serialNumber);
        List<BusinessTags> tags = source.getCallTags();
        List<BusinessTags> tagList = new ArrayList<>();
        if (tags == null) {
            return HtmlResult.success(tagList);
        }
        //只返回正确的标签
        for (BusinessTags tag : tags) {
            if (tag.getProValue() == BaseEntity.PROVALUE_YES) {
                tagList.add(tag);
            }
        }
        return HtmlResult.success(tagList);
    }

    @Override
    public HtmlResult getRulesBySerialNumber(String serialNumber, String workId) throws IOException, InvocationTargetException, IllegalAccessException {
        Source source = esUtil.getSourceBySerialNumber(serialNumber);
        Map<Long, Map<String, Integer>> rulessss = new HashMap<>();
        Long modelId = null;
        String modelName = null;
        for (WorkScores workScores : source.getWorkScores()) {
            if (workId.equals(workScores.getWorkId().toString())) {
                for (ModelRules mr : workScores.getModelRules()) {
                    Map<String, Integer> rule = new HashMap<>();
                    rule.put("fateful", mr.getFateful());
                    rule.put("useFor", mr.getUseFor());
                    rule.put("ruleScore", mr.getRuleScore());
                    modelId = mr.getModelId();
                    modelName = mr.getModelName();
                    rulessss.put(mr.getRuleId(), rule);
                }
            }
        }
        List<RuleInfosDto> ruleInfos = new ArrayList<>();
        for (Map.Entry<Long, Map<String, Integer>> rule : rulessss.entrySet()) {
            for (RuleInfos infos : source.getRuleInfos()) {
                if (infos.getRuleId().equals(rule.getKey())) {
                    RuleInfosDto dto = new RuleInfosDto();
                    ConvertUtils.register(new DateConverter(null), java.util.Date.class);
                    BeanUtils.copyProperties(dto, infos);
                    dto.setModelId(modelId);
                    dto.setModelName(modelName);
                    dto.setRuleScore(rule.getValue().get("ruleScore"));
                    dto.setUseFor(rule.getValue().get("useFor"));
                    dto.setFateful(rule.getValue().get("fateful"));
                    for (RuleDetails details : dto.getRuleDetails()) {
                        if (details.getVoiceSegments() == null || details.getVoiceSegments().isEmpty()) {
                            List<VoiceSegment> segments = new ArrayList<>();
                            VoiceSegment segment = new VoiceSegment();
                            segment.setStartTime(0.0);
                            segment.setEndTime((double)source.getVoiceInfo().getHoldDuration());
                            segments.add(segment);
                            details.setVoiceSegments(segments);
                        }
                    }
                    ruleInfos.add(dto);
                }
            }
        }
        return HtmlResult.success(ruleInfos);
    }

    @Override
    public HtmlResult getTestRulesBySerialNumber(String serialNumber, String workId) throws IOException {
        Source source = esUtil.getSourceBySerialNumber(serialNumber);
        for (TestInfos testInfos : source.getTestInfos()) {
            if (workId.equals(testInfos.getWorkId().toString())) {
                List<TestModelRules> modelRules = testInfos.getTestModelRules();
                for (TestModelRules test : modelRules) {
                    if (test.getVoiceSegments().isEmpty()) {
                        VoiceSegment voice = new VoiceSegment();
                        voice.setStartTime(0.0);
                        voice.setEndTime((double)source.getVoiceInfo().getHoldDuration());
                        List<VoiceSegment> voices = new ArrayList<>();
                        voices.add(voice);
                        test.setVoiceSegments(voices);
                    }
                }
                return HtmlResult.success(modelRules);
            }
        }
        return HtmlResult.success();
    }

    @Override
    public HtmlResult getWorkStatusById(HttpServletRequest request) throws IOException {
        String serialNumber = request.getParameter("serialNumber");//录音流水
        String workId = request.getParameter("workId");
        Source source = esUtil.getSourceBySerialNumber(serialNumber);
        for (WorkScores work : source.getWorkScores()) {
            if (workId.equals(work.getWorkId().toString())) {
                return HtmlResult.success(work.getProStatus());
            }
        }
        return HtmlResult.failure();
    }

    @Override
    public HtmlResult addTag(String serialNumber, String tagIds, String tagNames) throws IOException {
        Source source = esUtil.getSourceBySerialNumber(serialNumber);
        List<BusinessTags> tags = source.getCallTags();
        List<BusinessTags> zxList = new ArrayList<>();
        List<BusinessTags> xtList = new ArrayList<>();
        List<BusinessTags> zjList = new ArrayList<>();
        if (tags == null) {
            tags = new ArrayList<>();
        }
        for (BusinessTags tag : tags) {
            if (tag.getProType() == BaseEntity.PROTYPE_ZX) {
                zxList.add(tag);
            }
            if (tag.getProType() == BaseEntity.PROTYPE_SYS) {
                xtList.add(tag);
            }
        }
        if (!Strings.isNullOrEmpty(tagIds)) {
            String[] tagidArray = tagIds.split(",");
            String[] tagNamesArray = tagNames.split(",");
            for (int i = 0; i < tagidArray.length; i++) {
                int isExtis = 0;
                //判断是否es中存在，存在，为之前删除的
                for (BusinessTags tag : xtList) {
                    if (tag.getTagName().equals(tagNamesArray[i])) {
                        tag.setProValue(BaseEntity.PROVALUE_YES);
                        isExtis++;
                    }
                }
                //不存在，为新添加的
                if (isExtis == 0) {
                    BusinessTags tag = new BusinessTags();
                    tag.setTagId(Long.parseLong(tagidArray[i]));
                    tag.setTagName(tagNamesArray[i]);
                    tag.setProValue(BaseEntity.PROVALUE_YES);
                    tag.setProType(BaseEntity.PROTYPE_ZJ);
                    tag.setInputTime(DateFormatUtil.dateToString(new Date(), "yyyy-MM-dd HH:mm:ss"));
                    zjList.add(tag);
                }
            }
        }
        source.setCallTags(null);
        List<BusinessTags> tagsList = new ArrayList<>();
        if (!zxList.isEmpty()) {
            tagsList.addAll(zxList);
        }
        if (!xtList.isEmpty()) {
            tagsList.addAll(xtList);
        }
        tagsList.addAll(zjList);
        source.setCallTags(tagsList);
        //todo 有时间可以用script局部更新优化
        return esUtil.updateSource(source);
    }

    @Override
    public HtmlResult delTag(String serialNumber, String tagName) throws IOException {
        Source source = esUtil.getSourceBySerialNumber(serialNumber);
        List<BusinessTags> tags = source.getCallTags();
        BusinessTags tag1 = null;
        boolean is2 = false;
        for (BusinessTags tag : tags) {
            if ((tag.getProType() == BaseEntity.PROTYPE_ZX)) {
                continue;
            }
            if (tag.getTagName().equals(tagName)) {
                tag1 = tag;
                //系统添加的tag修改状态
                if (tag.getProType() == BaseEntity.PROTYPE_SYS) {
                    tag.setProValue(BaseEntity.PROVALUE_NO);
                }
                //质检员添加的tag真删除
                if (tag.getProType() == BaseEntity.PROTYPE_ZJ) {
                    is2 = true;
                }
                break;
            }
        }
        if (is2) {
            tags.remove(tag1);
        }
        //todo 有时间可以用script局部更新优化
        return esUtil.updateSource(source);
    }

    @Override
    public HtmlResult isRuleExit(HttpServletRequest request) throws IOException {
        String serialNumber = request.getParameter("serialNumber");//录音流水
        String workId = request.getParameter("workId");//任务Id
        String resMap = request.getParameter("resMap");//命中开始时间结束时间段 集合
        List<Map<String, Object>> boxList = new ArrayList<>();
        ObjectMapper objectMapper  = new ObjectMapper();
        if(!Strings.isNullOrEmpty(resMap)){
            boxList = objectMapper.readValue(resMap, objectMapper.getTypeFactory().constructCollectionType(List.class,Map.class));
        }
        List<VoiceSegment> voiceSegments = new ArrayList<>();
        for (Map<String, Object> map : boxList) {
            VoiceSegment voiceSegment = new VoiceSegment();
            voiceSegment.setEndTime(Double.parseDouble(map.get("endTime").toString()));
            voiceSegment.setStartTime(Double.parseDouble(map.get("startTime").toString()));
            voiceSegments.add(voiceSegment);
        }
        Source source = esUtil.getSourceBySerialNumber(serialNumber);
        List<Long> mrList = new ArrayList<>();
        for (WorkScores work : source.getWorkScores()) {
            if (workId.equals(work.getWorkId().toString())) {
                for (ModelRules mr : work.getModelRules()) {
                    mrList.add(mr.getRuleId());
                }
            }
        }
        List<RuleInfos> riList = new ArrayList<>();
        for (Long mr : mrList) {
            for (RuleInfos rule : source.getRuleInfos()) {
                if (rule.getRuleId().toString().equals(mr.toString())) {
                    riList.add(rule);
                }
            }
        }
        List<Long> ruleIdList = new ArrayList<>();
        for (RuleInfos rule : riList) {
            for (RuleDetails detail : rule.getRuleDetails()) {
                if (detail.getVoiceSegments().size() == voiceSegments.size()) {
                    int num = 0;
                    for (int i = 0; i < voiceSegments.size(); i++) {
                        if (detail.getVoiceSegments().get(i).getStartTime().toString().equals(voiceSegments.get(i).getStartTime().toString())
                                && detail.getVoiceSegments().get(i).getEndTime().toString().equals(voiceSegments.get(i).getEndTime().toString())
                        ) {
                            num ++;
                        }
                    }
                    if (num == voiceSegments.size() && !ruleIdList.contains(rule.getRuleId())) {
                        ruleIdList.add(rule.getRuleId());
                    }
                }
            }
        }
        return HtmlResult.success(ruleIdList);
    }

    @Override
    public HtmlResult getTagsList(String serialNumber) throws IOException {
        BusTagExample example = new BusTagExample();
        example.createCriteria().andIdIsNotNull();
        List<BusTag> tagList = busTagMapper.selectByExample(example);
        List<BusTag> busTags = new ArrayList<>(tagList);
        //todo 用指定字段查询优化
        Source source = esUtil.getSourceBySerialNumber(serialNumber);
        List<BusinessTags> tags = source.getCallTags();
        if (tags == null) {
            return HtmlResult.success(busTags);
        }
        for (BusinessTags tags1 : tags) {
            for (BusTag tag : tagList) {
                if (tags1.getProValue() == BaseEntity.PROVALUE_YES && tags1.getTagId().equals(tag.getId())) {
                    busTags.remove(tag);
                }
            }
        }
        return HtmlResult.success(busTags);
    }

    /**
     *  [
     *      {
     *          ruleId:
     *          [
     *                  {
     *                      detailNum:
     *                      proStatus:
     * 				        proNote:
     * 				        appealNote:
     * 				        modelId:
     *                  }
     * 		    ]
     *      }
     *  ]
     */
    @Override
    public HtmlResult updateRulesForSys(HttpServletRequest request) throws IOException {
        String serialNumber = request.getParameter("serialNumber");//录音流水
        String workId = request.getParameter("workId");//录音流水
        String resMap = request.getParameter("resMap");
        BusWork busWork = busWorkMapper.selectByPrimaryKey(Long.parseLong(workId));
        List<Map<String, Object>> boxList = new ArrayList<>();
        ObjectMapper objectMapper  = new ObjectMapper();
        if(!Strings.isNullOrEmpty(resMap)){
            boxList = objectMapper.readValue(resMap, objectMapper.getTypeFactory().constructCollectionType(List.class,Map.class));
        }
        //todo 用指定字段查询优化
        Source source = esUtil.getSourceBySerialNumber(serialNumber);
        Session session = SecurityUtils.getSubject().getSession();
        User user = (User) session.getAttribute(Constants.SESSION_USER_INFO);
        int userIdentity = (Integer) session.getAttribute("userIdentity");
        for (Map<String, Object> map : boxList) {
            String modelId = "";
            //修改规则模块先....
            for (RuleInfos rule : source.getRuleInfos()) {
                if (map.get("ruleId").toString().equals(rule.getRuleId().toString())) {
                    List<Map<String, Object>> dats = (List<Map<String, Object>>) map.get("dats");
                    for (Map<String, Object> dta : dats) {
                        for (RuleDetails ruleDe : rule.getRuleDetails()) {
                            if (ruleDe.getDetailNum().equals(dta.get("detailNum").toString())) {
                                if (BaseEntity.USERIDENTITY_ZX == userIdentity) {//坐席
                                    ruleDe.setProStatus(Integer.parseInt(dta.get("proStatus").toString()));
                                    ruleDe.setAppealNote(dta.get("appealNote").toString());
                                    ruleDe.setAppealTime(DateFormatUtil.dateToString(new Date(), "yyyy-MM-dd HH:mm:ss"));
                                    ruleDe.setAppealUserId(user.getId());
                                } else {//其它角色
                                    ruleDe.setProStatus(Integer.parseInt(dta.get("proStatus").toString()));
                                    //若是申诉成功、命中次数-1 并记录
                                    int proStatus = Integer.parseInt(dta.get("proStatus").toString());
                                    if (BaseEntity.SM_WORK_PROSTATUS_APPEAL_YES == proStatus) {
                                        ruleDe.setMatchStatus(BaseEntity.MATCHSTATUS_NO);
                                        rule.setRuleTimes(rule.getRuleTimes() - 1);
                                        map.put("ruleTimes", rule.getRuleTimes());
                                    }
                                    //质检员将结果加入申诉历史中
                                    ProcessedInfos processedInfo = new ProcessedInfos();
                                    processedInfo.setProStatus(Integer.parseInt(dta.get("proStatus").toString()));
                                    processedInfo.setProNote(dta.get("proNote").toString());
                                    processedInfo.setProTime(DateFormatUtil.dateToString(new Date(), "yyyy-MM-dd HH:mm:ss"));
                                    processedInfo.setProUserId(user.getId());
                                    processedInfo.setMatchStatus(ruleDe.getMatchStatus());
                                    processedInfo.setIsMissing(ruleDe.getIsMissing());
                                    processedInfo.setWorkId(Long.parseLong(workId));
                                    //坐席申诉信息
                                    processedInfo.setAppealNote(ruleDe.getAppealNote());
                                    processedInfo.setAppealTime(ruleDe.getAppealTime());
                                    processedInfo.setAppealUserId(ruleDe.getAppealUserId());
                                    List<ProcessedInfos> infosList = ruleDe.getProcessedInfos();
                                    if (infosList == null || infosList.isEmpty()) {
                                        infosList = new ArrayList<>();
                                    }
                                    infosList.add(processedInfo);
                                    ruleDe.setProcessedInfos(null);
                                    ruleDe.setProcessedInfos(infosList);
                                    //清空最后一次ruleDetails中的坐席的信息
                                    ruleDe.setAppealNote(null);
                                    ruleDe.setAppealUserId(null);
                                    ruleDe.setAppealTime(null);
                                }
                            }
                        }
                        modelId = dta.get("modelId").toString();
                    }
                    if (BaseEntity.USERIDENTITY_ZX == userIdentity) {//坐席，记录给规则为申诉过
                        rule.setProcessed(rule.getRuleTimes() + 1);
                    }
                }
            }
            //根据规则id获取规则模型信息
            BusModelRuleExample example = new BusModelRuleExample();
            example.createCriteria().andRuleidEqualTo(Long.parseLong(map.get("ruleId").toString())).andModelidEqualTo(Long.parseLong(modelId));
            List<BusModelRule> busModelRules = busModelRuleMapper.selectByExample(example);
            BusModelRule busModelRule = busModelRules.get(0);
            //满分
            BusModel model = modelMapper.selectByPrimaryKey(Long.parseLong(modelId));
            int fullScore = 100;
            if (model != null && model.getFullscore() != null) {
                fullScore = model.getFullscore();
            }
            boolean isAppealYes = false;
            //修改任务得分
            for (WorkScores work : source.getWorkScores()) {
                if (workId.equals(work.getWorkId().toString())) {//当前任务
                    //总任务状态
                    int workStatus = work.getProStatus();
                    if (BaseEntity.USERIDENTITY_ZX == userIdentity) {//坐席 && 当前操作的任务
                        work.setProStatus(BaseEntity.BIG_WORK_PROSTATUS_APPEAL_YES_20);
                        if (work.getAppealTimes() == null) {
                            work.setAppealTimes(1);
                        } else {
                            work.setAppealTimes(work.getAppealTimes() + 1);
                        }
                    } else {//其它角色
                        for (ModelRules mr : work.getModelRules()) {
                            if (mr.getRuleId().toString().equals(map.get("ruleId").toString())) {
                                List<Map<String, Object>> dats = (List<Map<String, Object>>) map.get("dats");
                                for (Map<String, Object> dta : dats) {
                                    //若是申诉成功、将减掉的分数加回去
                                    int proStatus = Integer.parseInt(dta.get("proStatus").toString());
                                    if (BaseEntity.SM_WORK_PROSTATUS_APPEAL_YES == proStatus) {
                                        Integer ruleTimes = (Integer) map.get("ruleTimes");
                                        mr.setRuleScore(esUtil.formatModelRuleScoure(
                                                mr.getScorePerTime(),
                                                mr.getFateful(),
                                                ruleTimes,
                                                busModelRule.getMaxscore(),
                                                fullScore
                                        ));
                                        isAppealYes = true;
                                    }
                                    //判断总任务状态
                                    if (work.getProStatus() == BaseEntity.BIG_WORK_PROSTATUS_APPEAL_YES_20) {//质检员 - 只能是复检完成
                                        workStatus = BaseEntity.BIG_WORK_PROSTATUS_RECHECK_YES_30;
                                    }
                                }
                            }
                        }
                        List<RuleInfos> ruleInfos = new ArrayList<>();
                        for (ModelRules modelRules : work.getModelRules()) {
                            for (RuleInfos ri : source.getRuleInfos()) {
                                if (modelRules.getRuleId().toString().equals(ri.getRuleId().toString())) {
                                    ruleInfos.add(ri);
                                }
                            }
                        }
                        work.setProStatus(workStatus);
                        work.setWorkScore(esUtil.formWorkScore(work.getModelRules(), ruleInfos, busWork.getScoreflag(), fullScore));
                        if (workId.equals(work.getWorkId().toString())) {//当前操作的任务
                            work.setProUserId(user.getId());
                            work.setProUserName(user.getUsername());
                        }
                    }
                    work.setUpdateTime(DateFormatUtil.dateToString(new Date(), "yyyy-MM-dd HH:mm:ss"));
                }
            }
            //非坐席人员操作，并且是申诉同意
            if (BaseEntity.USERIDENTITY_ZX != userIdentity && isAppealYes) {
                updateNowWorkScoreToOtherWorkScore(source, workId, modelId, map.get("ruleId").toString(), Integer.parseInt(map.get("ruleTimes").toString()), fullScore);
            }
        }
        //todo 有时间可以用script局部更新优化
        return esUtil.updateSource(source);
    }

    @Override
    public HtmlResult getTree(String workId) {
        //1.task
        Map<String, Object> task = new HashMap<>();
        task.put("id", workId);
        task.put("type", "task");
        task.put("text", busWorkMapper.selectByPrimaryKey(Long.parseLong(workId)).getWorkname());
        BusWorkModelExample wmExample = new BusWorkModelExample();
        wmExample.createCriteria().andWorkidEqualTo(Long.parseLong(workId));
        List<BusWorkModel> wmList = busWorkModelMapper.selectByExample(wmExample);
        //  2.model
        List<Object> modelList = new ArrayList<>();
        for (BusWorkModel wm : wmList) {
            Map<String, Object> model = new HashMap<>();
            model.put("id", wm.getModelid());
            model.put("type", "model");
            model.put("text", busModelMapper.selectByPrimaryKey(wm.getModelid()).getName());
            BusModelRuleExample mrExample = new BusModelRuleExample();
            mrExample.createCriteria().andModelidEqualTo(wm.getModelid());
            List<BusModelRule> rtList = busModelRuleMapper.selectByExample(mrExample);
            //     3.ruleType
            List<Object> ruleTypeList = new ArrayList<>();
            for (BusModelRule rt : rtList) {
                Map<String, Object> ruleType = new HashMap<>();
                ruleType.put("id", rt.getRuletypeid());
                ruleType.put("text", rt.getRuletypename());
                ruleType.put("type", "ruleType");
                ruleType.put("children", new ArrayList<>());
                if (!ruleTypeList.contains(ruleType)) {
                    ruleTypeList.add(ruleType);
                }
            }
            model.put("children", ruleTypeList);
            modelList.add(model);
        }
        task.put("children", modelList);
        return HtmlResult.success(task);
    }

    @Override
    public HtmlResult getRuleByTree(HttpServletRequest request) {
        Integer pageNum = null;//起始页
        Integer pageSize = null;//每页条数
        if (!Strings.isNullOrEmpty(request.getParameter("pageNum"))) {
            pageNum = Integer.parseInt(request.getParameter("pageNum"));//起始页
            pageSize = Integer.parseInt(request.getParameter("pageSize"));//每页条数
        }
        String workId = request.getParameter("workId");//每页条数
        String modelId = request.getParameter("modelId");//每页条数
        String ruleTypeId = request.getParameter("ruleTypeId");//每页条数
        String ruleName = request.getParameter("ruleName");//每页条数
        Map<String, Object> map = new HashMap<>();
        if (!Strings.isNullOrEmpty(workId)) {
            map.put("workId", workId);
        }
        if (!Strings.isNullOrEmpty(modelId)) {
            map.put("modelId", modelId);
        }
        if (!Strings.isNullOrEmpty(ruleTypeId)) {
            map.put("ruleTypeId", ruleTypeId);
        }
        if (!Strings.isNullOrEmpty(ruleName)) {
            map.put("ruleName", "%" + ruleName + "%");
        }
        if (pageNum != null) {
            Page<Map> page = new Page<>(pageNum+1, pageSize);
            return HtmlResult.success(busModelRuleMapper.getRuleByTree(page, map), page.getTotalCount());
        } else {
            return HtmlResult.success(busModelRuleMapper.getRuleByTree(map));
        }
    }

    @Override
    public HtmlResult addRulesForArti(HttpServletRequest request) throws IOException {
        String serialNumber = request.getParameter("serialNumber");//录音流水
        String workId = request.getParameter("workId");
        String modelIds = request.getParameter("modelId");//模型id
        String ruleIds = request.getParameter("ruleId");//规则id
        String proNote = request.getParameter("proNote");//处理原因
        String resMap = request.getParameter("resMap");//命中开始时间结束时间段 集合
        BusWork work = busWorkMapper.selectByPrimaryKey(Long.parseLong(workId));
        List<Map<String, Object>> boxList = new ArrayList<>();
        ObjectMapper objectMapper  = new ObjectMapper();
        if(!Strings.isNullOrEmpty(resMap)){
            boxList = objectMapper.readValue(resMap, objectMapper.getTypeFactory().constructCollectionType(List.class,Map.class));
        }
        List<VoiceSegment> voiceSegments = new ArrayList<>();
        for (Map<String, Object> map : boxList) {
            VoiceSegment voiceSegment = new VoiceSegment();
            voiceSegment.setStartTime(Double.parseDouble(map.get("startTime").toString()));
            voiceSegment.setEndTime(Double.parseDouble(map.get("endTime").toString()));
            voiceSegments.add(voiceSegment);
        }
        Session session = SecurityUtils.getSubject().getSession();
        User user = (User) session.getAttribute("userInfo");
        int userIdentity = (Integer) session.getAttribute("userIdentity");
        //todo 用指定字段查询优化
        Source source = esUtil.getSourceBySerialNumber(serialNumber);
        //ruleId为空，只改变任务状态
        if (Strings.isNullOrEmpty(ruleIds)) {
            //workScorse 装载数据
            for (WorkScores workScores : source.getWorkScores()) {
                if (workId.equals(workScores.getWorkId().toString())) {
                    workScores.setUpdateTime(DateFormatUtil.dateToString(new Date(), "yyyy-MM-dd HH:mm:ss"));
                    workScores.setProFlag(BaseEntity.PROFLAG_ART);
                    if (BaseEntity.USERIDENTITY_ZX != userIdentity) {//非坐席人员 && 是当前操作任务
                        workScores.setProUserId(user.getId());
                        workScores.setProUserName(user.getUsername());
                    }
                    return esUtil.updateSource(source);
                }
            }
        }
        String[] modelIdArr = modelIds.split(",");
        String[] ruleIdArr = ruleIds.split(",");
        for (int i = 0; i < ruleIdArr.length; i++) {
            //根据规则id获取规则模型信息
            BusModelRuleExample example = new BusModelRuleExample();
            example.createCriteria().andRuleidEqualTo(Long.parseLong(ruleIdArr[i])).andModelidEqualTo(Long.parseLong(modelIdArr[i]));
            List<BusModelRule> busModelRules = busModelRuleMapper.selectByExample(example);
            BusModelRule busModelRule = busModelRules.get(0);
            boolean isExcit = true;
            int ruleTimes = 0;
            //ruleInfos   装载数据
            for (RuleInfos rule : source.getRuleInfos()) {
                if (ruleIdArr[i].equals(rule.getRuleId().toString())) {//存在该规则
                    RuleDetails details = new RuleDetails();
                    details.setDetailNum(UUID.randomUUID().toString());
                    details.setVoiceSegments(voiceSegments);
                    details.setInputTime(DateFormatUtil.dateToString(new Date(), "yyyy-MM-dd HH:mm:ss"));
                    details.setProUserId(user.getId());
                    details.setProTime(DateFormatUtil.dateToString(new Date(), "yyyy-MM-dd HH:mm:ss"));
                    details.setAppealTime(DateFormatUtil.dateToString(new Date(), "yyyy-MM-dd HH:mm:ss"));
                    details.setProNote(proNote);
                    details.setProStatus(BaseEntity.SM_WORK_PROSTATUS_APPEAL_BEGIN);
                    details.setMatchStatus(BaseEntity.MATCHSTATUS_YES);
                    details.setIsMissing(BaseEntity.ISMISSING_YES);
                    List<RuleDetails> detailsList = rule.getRuleDetails();
                    detailsList.add(details);
                    rule.setRuleDetails(null);
                    rule.setRuleDetails(detailsList);
                    isExcit = false;
                    rule.setRuleTimes(rule.getRuleTimes() + 1);
                    ruleTimes = rule.getRuleTimes();
                }
            }
            if (isExcit) {//不存在
                RuleDetails detail = new RuleDetails();
                detail.setDetailNum(UUID.randomUUID().toString());
                detail.setVoiceSegments(voiceSegments);
                detail.setInputTime(DateFormatUtil.dateToString(new Date(), "yyyy-MM-dd HH:mm:ss"));
                detail.setProUserId(user.getId());
                detail.setProTime(DateFormatUtil.dateToString(new Date(), "yyyy-MM-dd HH:mm:ss"));
                detail.setAppealTime(DateFormatUtil.dateToString(new Date(), "yyyy-MM-dd HH:mm:ss"));
                detail.setProNote(proNote);
                detail.setProStatus(BaseEntity.SM_WORK_PROSTATUS_APPEAL_BEGIN);
                detail.setMatchStatus(BaseEntity.MATCHSTATUS_YES);
                detail.setIsMissing(BaseEntity.ISMISSING_YES);
                List<RuleDetails> detailsList = new ArrayList<>();
                detailsList.add(detail);
                //ruleInfo
                RuleInfos ruleInfos = new RuleInfos();
                ruleInfos.setRuleId(Long.parseLong(ruleIdArr[i]));
                ruleInfos.setRuleName(busModelRule.getRulename());
                ruleInfos.setRuleTimes(1);
                ruleInfos.setRuleDetails(detailsList);
                List<RuleInfos> rules = source.getRuleInfos();
                rules.add(ruleInfos);
                ruleTimes = ruleInfos.getRuleTimes();
            }
            //满分
            BusModel model = modelMapper.selectByPrimaryKey(busModelRule.getModelid());
            int fullScore = 100;
            if (model != null && model.getFullscore() != null) {
                fullScore = model.getFullscore();
            }
            //workScorse 装载数据
            for (WorkScores workScores : source.getWorkScores()) {
                if (workId.equals(workScores.getWorkId().toString())) {
                    for (ModelRules modelRules : workScores.getModelRules()) {
                        if (ruleIdArr[i].equals(modelRules.getRuleId().toString())
                                && modelIdArr[i].equals(modelRules.getModelId().toString())
                        ) {//存在该规则 //命中量+1、分值加
                            modelRules.setRuleScore(esUtil.formatModelRuleScoure(
                                    modelRules.getScorePerTime(),
                                    modelRules.getFateful(),
                                    ruleTimes,
                                    busModelRule.getMaxscore(),
                                    fullScore
                            ));
                        }
                    }
                    //若规则是之前没有的，则只对本任务进行修改
                    if (workId.equals(workScores.getWorkId().toString())) {//不存在 && 是当前操作任务
                        List<ModelRules> modelRulesList = workScores.getModelRules();
                        boolean isAdd = true;
                        for (ModelRules mr : modelRulesList) {
                            if (mr.getModelId().toString().equals(modelIdArr[i])
                                    && mr.getRuleId().toString().equals(ruleIdArr[i]))
                            {
                                isAdd = false;
                            }
                        }
                        if (isAdd) {
                            ModelRules modelRule = new ModelRules();
                            modelRule.setModelId(Long.parseLong(modelIdArr[i]));
                            modelRule.setModelName(busModelMapper.selectByPrimaryKey(Long.parseLong(modelIdArr[i])).getName());
                            modelRule.setRuleId(Long.parseLong(ruleIdArr[i]));
                            modelRule.setRuleName(busModelRule.getRulename());
                            modelRule.setUseFor(busModelRule.getUserfor());
                            Integer fateful = busModelRule.getFateful();
                            //加分规则
                            if (busModelRule.getSignscore() != null && busModelRule.getSignscore() > 0) {
                                fateful = -1;
                            }
                            modelRule.setFateful(fateful);
                            if (modelRule.getFateful() == BaseEntity.FATEFUL_ART) {//致命性规则
                                if (busModelRule.getMaxscore() == null) {
                                    modelRule.setRuleScore(-100);
                                } else {
                                    modelRule.setRuleScore(busModelRule.getMaxscore());
                                }
                            } else {//非致命性规则
                                if (busModelRule.getMaxscore() != null
                                        && Math.abs(busModelRule.getMaxscore()) - Math.abs(busModelRule.getScorepertime()) <= 0) {
                                    modelRule.setRuleScore(busModelRule.getMaxscore());
                                } else {
                                    modelRule.setRuleScore(busModelRule.getScorepertime());
                                }
                            }
                            modelRule.setScorePerTime(busModelRule.getScorepertime());
                            modelRulesList.add(modelRule);
                        }
                    }
                    List<RuleInfos> ruleInfos = new ArrayList<>();
                    for (ModelRules modelRules : workScores.getModelRules()) {
                        if (modelRules.getModelId().toString().equals(modelIdArr[i])
                                && modelRules.getRuleId().toString().equals(ruleIdArr[i]))
                        {
                            Integer fateful = busModelRule.getFateful();
                            //加分规则
                            if (busModelRule.getSignscore() != null && busModelRule.getSignscore() > 0) {
                                fateful = -1;
                            }
                            modelRules.setFateful(fateful);
                        }
                        for (RuleInfos ri : source.getRuleInfos()) {
                            if (modelRules.getRuleId().toString().equals(ri.getRuleId().toString())) {
                                ruleInfos.add(ri);
                            }
                        }
                    }
                    workScores.setWorkScore(esUtil.formWorkScore(workScores.getModelRules(), ruleInfos, work.getScoreflag(), fullScore));
                    workScores.setUpdateTime(DateFormatUtil.dateToString(new Date(), "yyyy-MM-dd HH:mm:ss"));
                    workScores.setProFlag(BaseEntity.PROFLAG_ART);
                    if (BaseEntity.USERIDENTITY_ZX != userIdentity && workId.equals(workScores.getWorkId().toString())) {//非坐席人员 && 是当前操作任务
                        workScores.setProUserId(user.getId());
                        workScores.setProUserName(user.getUsername());
                    }
                }
            }
            updateNowWorkScoreToOtherWorkScore(source, workId, modelIdArr[i], ruleIdArr[i], ruleTimes, fullScore);
        }
        //todo 有时间可以用script局部更新优化
        return esUtil.updateSource(source);
    }

    @Override
    public HtmlResult delRulesForArti(HttpServletRequest request) throws IOException {
        String serialNumber = request.getParameter("serialNumber");//录音流水
        String workId = request.getParameter("workId");//模型ids
        String modelId = request.getParameter("modelId");//模型ids
        String ruleId = request.getParameter("ruleId");//规则ids
        String detailNum = request.getParameter("detailNum");//序号
        String postType = request.getParameter("postType");//序号
        Session session = SecurityUtils.getSubject().getSession();
        User user = (User) session.getAttribute("userInfo");
        Integer userIdentity = (Integer) session.getAttribute("userIdentity");
        BusWork work = busWorkMapper.selectByPrimaryKey(Long.parseLong(workId));
        //todo 用指定字段查询优化
        int ruleTimes = 1;
        Source source = esUtil.getSourceBySerialNumber(serialNumber);
        for (RuleInfos rule : source.getRuleInfos()) {
            if (ruleId.equals(rule.getRuleId().toString())) {
                for (RuleDetails detail : rule.getRuleDetails()) {
                    if (detailNum.equals(detail.getDetailNum())) {
                        if ("del".equals(postType)) {
                            rule.getRuleDetails().remove(detail);
                        } else {
                            detail.setMatchStatus(BaseEntity.MATCHSTATUS_NO);
                        }
                        detail.setProUserId(user.getId());
                        detail.setProTime(DateFormatUtil.dateToString(new Date(), "yyyy-MM-dd HH:mm:ss"));
                        rule.setRuleTimes(rule.getRuleTimes() - 1);
                        ruleTimes = rule.getRuleTimes();
                        break;
                    }
                }
            }
        }
        List<RuleInfos> ruleInfosList = new ArrayList<>();
        for (RuleInfos rule : source.getRuleInfos()) {
            if (rule.getRuleDetails().isEmpty()) {
                continue;
            }
            ruleInfosList.add(rule);
        }
        //满分
        BusModel model = modelMapper.selectByPrimaryKey(Long.parseLong(modelId));
        int fullScore = 100;
        if (model != null && model.getFullscore() != null) {
            fullScore = model.getFullscore();
        }
        source.setRuleInfos(null);
        source.setRuleInfos(ruleInfosList);
        for (WorkScores workScores : source.getWorkScores()) {
            if (workId.equals(workScores.getWorkId().toString())) {
                for (ModelRules modelRules : workScores.getModelRules()) {
                    if (ruleId.equals(modelRules.getRuleId().toString())) {//存在该规则
                        BusModelRuleExample example = new BusModelRuleExample();
                        example.createCriteria().andRuleidEqualTo(modelRules.getRuleId()).andModelidEqualTo(modelRules.getModelId());
                        List<BusModelRule> busModelRules = busModelRuleMapper.selectByExample(example);
                        BusModelRule busModelRule = busModelRules.get(0);
                        Integer max = busModelRule.getMaxscore();
                        modelRules.setRuleScore(esUtil.formatModelRuleScoure(
                                modelRules.getScorePerTime(),
                                modelRules.getFateful(),
                                PubMethod.getRuleTimeByRuleId(source.getRuleInfos(), ruleId),
                                max,
                                fullScore
                        ));
                    }
                }
                if ("judge".equals(postType)) {//点击“系统误判”
                    workScores.setProFlag(BaseEntity.PROFLAG_ART);
                }
                //
                List<RuleInfos> ruleInfos = new ArrayList<>();
                for (ModelRules modelRules : workScores.getModelRules()) {
                    for (RuleInfos ri : source.getRuleInfos()) {
                        if (modelRules.getRuleId().toString().equals(ri.getRuleId().toString())) {
                            ruleInfos.add(ri);
                        }
                    }
                }
                workScores.setWorkScore(esUtil.formWorkScore(workScores.getModelRules(), ruleInfos, work.getScoreflag(), fullScore));
                workScores.setUpdateTime(DateFormatUtil.dateToString(new Date(), "yyyy-MM-dd HH:mm:ss"));
                if (BaseEntity.USERIDENTITY_ZX != userIdentity) {//非坐席人员
                    workScores.setProUserId(user.getId());
                    workScores.setProUserName(user.getUsername());
                }
            }
        }
        updateNowWorkScoreToOtherWorkScore(source, workId, modelId, ruleId, ruleTimes, fullScore);
        return esUtil.updateSource(source);
    }

    /**
     * 修改一个任务分数，当前音频中用到这个规则的其他任务的分数也会变化
     * @param source -
     * @param workId -
     * @param modelId -
     * @param ruleId -
     * @param ruleTimes -
     * @param fullScore -
     */
    private void updateNowWorkScoreToOtherWorkScore(Source source, String workId, String modelId, String ruleId, int ruleTimes, int fullScore) {
        List<Long> workScoreIds = new ArrayList<>();
        for (WorkScores workScores : source.getWorkScores()) {
            if (!workId.equals(workScores.getWorkId().toString())) {
                for (ModelRules mr : workScores.getModelRules()) {
                    if (mr.getModelId().toString().equals(modelId) && mr.getRuleId().toString().equals(ruleId)) {
                        workScoreIds.add(workScores.getWorkId());
                    }
                }
            }
        }
        //根据规则id获取规则模型信息
        BusModelRuleExample example = new BusModelRuleExample();
        example.createCriteria().andRuleidEqualTo(Long.parseLong(ruleId)).andModelidEqualTo(Long.parseLong(modelId));
        List<BusModelRule> busModelRules = busModelRuleMapper.selectByExample(example);
        BusModelRule busModelRule = busModelRules.get(0);
        for (Long workScoreId : workScoreIds) {
            for (WorkScores workScores : source.getWorkScores()) {
                if (workScoreId.toString().equals(workScores.getWorkId().toString())) {
                    for (ModelRules modelRules : workScores.getModelRules()) {
                        if (ruleId.equals(modelRules.getRuleId().toString())
                                && modelId.equals(modelRules.getModelId().toString())
                        ) {//存在该规则 //命中量+1、分值加
                            modelRules.setRuleScore(esUtil.formatModelRuleScoure(
                                    modelRules.getScorePerTime(),
                                    modelRules.getFateful(),
                                    ruleTimes,
                                    busModelRule.getMaxscore(),
                                    fullScore
                            ));
                        }
                    }
                    BusWork work1 = busWorkMapper.selectByPrimaryKey(workScoreId);
                    if (work1 == null) {
                        continue;
                    }
                    List<RuleInfos> ruleInfos = new ArrayList<>();
                    for (ModelRules modelRules : workScores.getModelRules()) {
                        for (RuleInfos ri : source.getRuleInfos()) {
                            if (modelRules.getRuleId().toString().equals(ri.getRuleId().toString())) {
                                ruleInfos.add(ri);
                            }
                        }
                    }
                    workScores.setWorkScore(esUtil.formWorkScore(workScores.getModelRules(), ruleInfos, work1.getScoreflag(), fullScore));
                }
            }
        }
    }
}
